using System;
using System.Collections.Generic;
using System.Threading;

namespace ApiScanner.Core
{
	public static class ConfigurationKnownTypes
	{
		private static readonly Dictionary<string, Type> _ConfigurationElementTypes = new Dictionary<string, Type>();
		private static readonly ReaderWriterLockSlim _ConfigurationElementTypesLock = new ReaderWriterLockSlim();

		public static bool TryGetType(string name, out SerializableConfigurationElement result)
		{
			try
			{
				_ConfigurationElementTypesLock.EnterReadLock();

				Type type;
				if (_ConfigurationElementTypes.TryGetValue(name, out type))
				{
					result = (SerializableConfigurationElement) Activator.CreateInstance(type);
					
					return true;
				}
				else
				{
					result = null;
					return false;
				}
			}
			finally
			{
				_ConfigurationElementTypesLock.ExitReadLock();
			}
		}

		public static void RegisterConfigurationElementType<T>(string id)
			where T: SerializableConfigurationElement
		{
			RegisterConfigurationElementType(id, typeof(T));
		}

		public static void RegisterConfigurationElementType(string id, Type type)
		{
			if (string.IsNullOrEmpty(id)) throw new ArgumentNullException("id");
			if (type == null) throw new ArgumentNullException("type");
			if (!type.IsSubclassOf(typeof(SerializableConfigurationElement)))
			{
				throw new ArgumentException("type", string.Format("The type {0} must be a subclass of {1}.", type.FullName,
				                                                  typeof(SerializableConfigurationElement).FullName));
			}
			try
			{
				_ConfigurationElementTypesLock.EnterWriteLock();
				_ConfigurationElementTypes[id] = type;
			}
			finally
			{
				_ConfigurationElementTypesLock.ExitWriteLock();
			}
		}
	}
}